package client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Arrays;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import sameClasses.NetworkPacket;

public class Client {

  private static InetAddress ip;
  private static ClientOrb myOrb;
  private static String keystorefile;
  private static String keystorepw;
  private static int port;

  public Client(String hostname, int port, String keystorefile,
      String keystorepw) throws IOException {
    Client.port = port;
    Client.ip = InetAddress.getByName(hostname);
    Client.keystorefile = keystorefile;
    Client.keystorepw = keystorepw;
    Client.myOrb = new ClientOrb(ip, port, keystorefile, keystorepw);
  }

  public Object sendToServer(NetworkPacket packet) throws IOException {
    myOrb = new ClientOrb(ip, port, keystorefile, keystorepw);
    return myOrb.sendToServer(packet);
  }

  public boolean closeConnection() {
    return myOrb.closeConnection();
  }

}

class ClientOrb {
  Object responseFromServerOrb;

  InetAddress ipZuServer;
  Socket server;
  int port;
  ObjectOutputStream out = null;
  ObjectInputStream is = null;
  SSLSocket socket = null;
  private String keystorefile;
  private String keystorepw;

  public ClientOrb(InetAddress givenIp, int port, String keystorefile,
      String keystorepw) throws IOException {
    this.ipZuServer = givenIp;
    this.port = port;
    this.keystorefile = keystorefile;
    this.keystorepw = keystorepw;
    System.out.println("clientOrb initialized");
    System.setProperty("javax.net.ssl.trustStore", keystorefile); // Truststore File in den Umgebungsvariablen festlegen
    System.setProperty("javax.net.ssl.trustStorePassword", keystorepw); // Truststore Passwort in den Umgebungsvariablen festlegen
    SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); // Erzeugt eine SSLSocketFactory mit Standardkonfiguration
    try {
      socket = (SSLSocket) factory.createSocket(ipZuServer, port);
      //socket.setEnabledCipherSuites(new String[] {"TLS_RSA_WITH_AES_256_CBC_SHA"}); // nur TLS mit AES 256 CBC SHA zulassen => FUTURE USE
      out = new ObjectOutputStream(socket.getOutputStream());
      is = new ObjectInputStream(socket.getInputStream());
      System.out.println("clientOrb started");
    } catch (IOException e) {
      mainFrame.errorPopup(e.getMessage());
    }

  }

  public Object sendToServer(NetworkPacket packet) {
    responseFromServerOrb = null;
    try {
      out.writeObject(packet);
      responseFromServerOrb = is.readObject();
      out.flush();
      return responseFromServerOrb;
    } catch (Exception e) {
      mainFrame.errorPopup(e.getMessage());
    }
    return false;
  }

  public boolean closeConnection() {
    try {
      out.close();
      is.close();
      socket.close();
      return true;
    } catch (IOException e) {
      e.printStackTrace();
    }
    return false;
  }
}